package com.zxy.zxyrpc.server.tcp;

import com.zxy.zxyrpc.exception.RpcException;
import com.zxy.zxyrpc.model.ErrorCode;
import com.zxy.zxyrpc.model.RpcRequest;
import com.zxy.zxyrpc.model.RpcResponse;
import com.zxy.zxyrpc.protocol.*;
import com.zxy.zxyrpc.registry.LocalRegistry;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * 请求处理器
 *
 * @author zxy
 * @since 2025/5/11
 **/
public class TcpServerHandler implements Handler<NetSocket> {

    @Override
    public void handle(NetSocket socket) {
        socket.handler(buffer -> {
            // 接受请求，解码
            ProtocolMessage<RpcRequest> protocolMessage;
            try {
                protocolMessage = (ProtocolMessage<RpcRequest>) ProtocolMessageDecoder.decode(buffer);
            } catch (IOException e) {
                throw new RpcException(ErrorCode.OPERATION_ERROR, "协议消息解码错误");
            }

            // 处理请求,响应封装
            RpcRequest req = protocolMessage.getBody();
            RpcResponse res = new RpcResponse();
            try {
                // 获取要调用的服务实现类，通过反射调用
                Class<?> implClass = LocalRegistry.get(req.getServiceName());
                Method method = implClass.getMethod(req.getMethodName(), req.getParameterTypes());
                Object result = method.invoke(implClass.newInstance(), req.getArgs());
                // 封装返回结果
                res.setData(result);
                res.setDateType(method.getReturnType());
                res.setMessage("ok");
            } catch (Exception e) {
                e.printStackTrace();
                res.setMessage(e.getMessage());
                res.setException(e);
            }

            // 构建响应头
            ProtocolMessage.Header header = protocolMessage.getHeader();
            header.setType((byte) ProtocolMessageTypeEnum.RES.getKey());
            header.setStatus((byte) ProtocolMessageStatusEnum.OK.getValue());
            ProtocolMessage<RpcResponse> resProtocolMessage = new ProtocolMessage<>(header, res);
            try {
                Buffer encode = ProtocolMessageEncoder.encode(resProtocolMessage);
                socket.write(encode);
            } catch (IOException e) {
                throw new RpcException(ErrorCode.OPERATION_ERROR, "协议消息解码错误");
            }
        });
    }
}
